/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package View;

import Controller.Table;
import Controller.SelectPokemon;
import Pokemons.Pokemon;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import Missiles.Missile;
import Controller.SelectZombie;
import Pokemons.Pikachu;
import Zombies.Zombie;

/**
 * Autores:
 * Hugo Hiroshi Yamamura
 * Marina Coimbra Viviani
 * 
 * Classe BattleCamp
 * Campo de batalha entre pokemons e zumbis
 */
public class BattleCamp extends JPanel implements ActionListener{
    
    Scenery scene = new Scenery();
    
    private Timer timer;
    private Pokemon mon;
    private ArrayList aliens;
    private boolean ingame;
    private int B_WIDTH;
    private int B_HEIGHT;
    private int ZOMBIECREATION = 200;
    private int ZOMBIEKILLED = 0;
    private int COUNTDOWN = 3;
    
    private SelectPokemon sel = new SelectPokemon();
    
    private int times;
    
    private int finished;
    
     /*
     * Construtor BattleCamp
     * Funcionamento: aplica listeners ao JFrame e prepara o panel para
     * a dinâmica do jogo.
     * 
     * 
     */
    public BattleCamp(JFrame frame){
        
        TAdapter tada = new TAdapter();
        frame.addKeyListener(tada);
        frame.addMouseListener(new MAdapter());
        this.setFocusable(true);
        setBackground(Color.BLACK);
        setDoubleBuffered(true);
        setVisible(true);
        setFocusable(true);
        
        
        ingame = true;
        
        B_HEIGHT = 720;
        B_WIDTH = 600;

        setSize(720, 480);

        mon = new Pikachu(400,400);

       aliens = new ArrayList();

        timer = new Timer(20, this);
        timer.start();
        times = 0;
        
        scene = new Scenery();
        
        
    }
    
  
    @Override
 public void addNotify() {
        super.addNotify();
        B_WIDTH = getWidth();
        B_HEIGHT = getHeight();   
    }


      /*
     * 
     * Método paint
     * Aciona o desenhar de todas as classes envolvidas na dinâmica do jogo
     * 
     */

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        
        if(COUNTDOWN <= 0)
            ingame = false;
        

        if (this.ingame) {

            Graphics2D g2d = (Graphics2D)g;
            g2d.drawImage(scene.getImage(), 0 , 0, this);
            
            mon.paint(g2d, this);
            

        ArrayList ms = mon.getMissiles();

            for (int i = 0; i < ms.size(); i++) {
                Missile m = (Missile)ms.get(i);
                m.paint(g2d, this);
            }

            for (int i = 0; i < aliens.size(); i++) {
                Zombie a = (Zombie)aliens.get(i);
                if (a.isVisible())
                    a.paint(g2d,this);
            }
            
            g2d.drawImage(scene.getPoint(), 300, 225, this);

            g2d.setColor(Color.BLACK);
            Font small = new Font("Helvetica", Font.BOLD, 14);
            FontMetrics metr = this.getFontMetrics(small);
            g2d.drawString("Zombies killed: " + ZOMBIEKILLED, 330, 250);

            g2d.drawImage(scene.getImage2(), -50 , 250, this);
            g2d.drawImage(scene.getWomanimg(), 35, 370, this);
            g2d.drawImage(scene.getManimg(), 90,390,this);
            } 
            else {
                    String msg = "Parabens! Voce Matou " + String.valueOf(ZOMBIEKILLED)+ " Pokezumbis!";

                   Font small = new Font("Helvetica", Font.BOLD, 14);
                    FontMetrics metr = this.getFontMetrics(small);

                    g.setColor(Color.white);
                    g.setFont(small);
                    g.drawString(msg, (B_WIDTH - metr.stringWidth(msg)) / 2,
                                 B_HEIGHT / 2);
                }

        Toolkit.getDefaultToolkit().sync();
        g.dispose();
    }


    
     /*
     * 
     * Método actionPerformed
     * Funcionamento: ativado pelo timer. Executa as ações do jogo.
     * Incita todos os pokémons a andar, cria mais zumbis,
     * chama o método que verifica colisões.
     * 
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        if(ZOMBIECREATION == 0)
            ZOMBIECREATION = 1/times;
        if(times % ZOMBIECREATION == 0){
            ZOMBIECREATION--;
            SelectZombie sz = new SelectZombie();
           
            aliens.add( sz.SelectZombieKind());
        }
        
        if (aliens.size()==0) {
            ingame = false;
        }

        ArrayList ms = mon.getMissiles();

        for (int i = 0; i < ms.size(); i++) {
            Missile m = (Missile) ms.get(i);
            if (m.isVisible()) 
                m.move();
            else ms.remove(i);
        }

        for (int i = 0; i < aliens.size(); i++) {
            Zombie a = (Zombie) aliens.get(i);
            if (a.isVisible()) 
                a.move(times);
            else aliens.remove(i);
        }

        mon.move(times++);
        checkCollisions();
        repaint();  
    }

    
      /*
     * 
     * Método checkCollisions
     * Funcionamento: Procura colisões entre o pokemon e os zumbis.
     * Procura colisões entre os zumbis e os mísseis.
     * Verifica se as colisões são válidas
     * 
     */
    public void checkCollisions() {
        
        Table table = new Table();

        Rectangle r3 = mon.getBounds();

        for (int j = 0; j<aliens.size(); j++) {
            Zombie a = (Zombie) aliens.get(j);
            Rectangle r2 = a.getBounds();
            
            if(a.getX() < table.getXBEGIN())
            {
                this.COUNTDOWN = this.COUNTDOWN -1;
                a.setVisible(false);
                aliens.remove(j);
            }
            
            if (r3.intersects(r2)) {
                mon.setVisible(false);
                a.setVisible(false);
                ingame = false;
            }
        }

        ArrayList ms = mon.getMissiles();

        for (int i = 0; i < ms.size(); i++) {
            Missile m =  (Missile) ms.get(i);

            Rectangle r1 = m.getBounds();

            for (int j = 0; j<aliens.size(); j++) {
                Zombie a = (Zombie) aliens.get(j);
                
                
                    
                Rectangle r2 = a.getBounds();
               // System.out.println("Type Zombie" + a.getType() + "Missil " + m.getType());
                if ((r1.intersects(r2)) &&( a.getType() == m.getType())) {
                    ZOMBIEKILLED++;
                    m.setVisible(false);
                    a.dealCollision();
                }
            }
        }
    }

 
    /*
     * Classe Privada TAdapter
     * Funcionamento: classe responsável por captaros eventos de teclado.

     */
    private class TAdapter extends KeyAdapter {


        public void keyReleased(KeyEvent e) {
  
            mon.keyReleased(e);
        }

        public void keyPressed(KeyEvent e) {
            mon.keyPressed(e);
        }
    }
   
    
      /*
     * Classe Privada MAdapter
     * Funcionamento: classe responsável por captaros eventos de teclado.
     */
    private class MAdapter extends MouseAdapter{
        
        @Override
        public void mouseClicked(MouseEvent e){
  
            
            int x = sel.findCol(e.getX());
            int y = sel.findRow(e.getY());

            if( x != -1 && y != -1){
                sel.selecting(e.getX(), e.getY());
                mon = sel.getPoke(mon.getX(), mon.getY());
            }



          
        }
    }
}